/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.table.cellRenderer;

import java.awt.Component;
import java.awt.Desktop;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Objects;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

/**
 * Referencia: http://java-swing-tips.blogspot.com.br/2009/02/hyperlink-in-jtable-cell.html <br>
 * <br>
 * 
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.table.cellRenderer
 * @date 16/03/2014 - 09:38:40
 */
public class URLRenderer extends DefaultTableCellRenderer implements MouseListener, MouseMotionListener {
	
	private static final long serialVersionUID = -4945121930119562343L;
	
	private int row = -1;
	
	private int col = -1;
	
	private boolean isRollover = false;
	
	@Override
	public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
	
		super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
		
		final String str = Objects.toString(value, "");
		
		//
		if(this.row == row && col == column && table.isCellEditable(row, col)) {
			
			//
			if( !table.isEditing() && this.row == row && col == column && isRollover) {
				
				setText("<html><u><font color='blue'>" + str);
				
			}else if(hasFocus) {
				
				setText("<html><font color='blue'>" + str);
				
			}else {
				
				setText(str);
			}
			
		}else {
			
			setText(str);
		}
		
		return this;
	}
	
	@Override
	public void mouseClicked(final MouseEvent mouseEvent) {
	
		final JTable table = (JTable)mouseEvent.getSource();
		
		final Point pt = mouseEvent.getPoint();
		
		final int ccol = table.columnAtPoint(pt);
		
		//
		if(isURLColumn(table, ccol)) {
			
			final int crow = table.rowAtPoint(pt);
			
			//
			if(table.isCellEditable(crow, ccol)) {
				
				final URL url = (URL)table.getValueAt(crow, ccol);
				
				//
				if(url != null) {
					
					try {
						//
						if(Desktop.isDesktopSupported()) {
							
							Desktop.getDesktop().browse(url.toURI());
						}
						
					}catch(URISyntaxException | IOException exception) {
						
						exception.printStackTrace();
					}
				}
			}
		}
	}
	
	@Override
	public void mouseDragged(final MouseEvent mouseEvent) { /* not needed */
	
	}
	
	@Override
	public void mouseEntered(final MouseEvent mouseEvent) { /* not needed */
	
	}
	
	@Override
	public void mouseExited(final MouseEvent mouseEvent) {
	
		final JTable table = (JTable)mouseEvent.getSource();
		
		//
		if(isURLColumn(table, col)) {
			
			table.repaint(table.getCellRect(row, col, false));
			
			row = -1;
			col = -1;
			isRollover = false;
		}
	}
	
	@Override
	public void mouseMoved(final MouseEvent mouseEvent) {
	
		final JTable table = (JTable)mouseEvent.getSource();
		
		final Point pt = mouseEvent.getPoint();
		
		final int prev_row = row;
		final int prev_col = col;
		final boolean prev_ro = isRollover;
		
		row = table.rowAtPoint(pt);
		col = table.columnAtPoint(pt);
		isRollover = isURLColumn(table, col);
		
		//
		if(row == prev_row && col == prev_col && isRollover == prev_ro || !isRollover && !prev_ro) {
			
			return;
		}
		
		Rectangle repaintRect;
		
		//
		if(isRollover) {
			
			final Rectangle r = table.getCellRect(row, col, false);
			repaintRect = prev_ro ? r.union(table.getCellRect(prev_row, prev_col, false)) : r;
			
		}else {
			
			repaintRect = table.getCellRect(prev_row, prev_col, false);
		}
		
		table.repaint(repaintRect);
	}
	
	@Override
	public void mousePressed(final MouseEvent mouseEvent) { /* not needed */
	
	}
	
	@Override
	public void mouseReleased(final MouseEvent mouseEvent) { /* not needed */
	
	}
	
	/**
	 * @param table
	 * @param column
	 */
	private static boolean isURLColumn(final JTable table, final int column) {
	
		return column >= 0 && table.getColumnClass(column).equals(URL.class);
	}
}
